﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using static System.Net.Mime.MediaTypeNames;
using System.Web.Caching;
using System.Web.UI.WebControls;
using System.IO.Compression;
using System.IO;

namespace Wsq.Utils.DoNetFramework40.Socket.tools
{
    public class HttpResponse
    {
        Wsq.Utils.DoNetFramework40.Socket.Server server;
        SocketAsyncEventArgs e;
        HttpSession httpSession;
        List<string> CookieAppend = new List<string>();
        const string magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        public HttpResponse(SocketAsyncEventArgs e, Wsq.Utils.DoNetFramework40.Socket.Server server, HttpSession httpSession,bool addJSessionID) 
        {
            this.e = e;
            this.server = server;
            this.httpSession = httpSession;
            if (addJSessionID)
            {
                CookieAppend.Add("JSessionID="+httpSession.JSessionID);
                //CookieAppend.Add("Set-Cookie: "++"; Path=/; HttpOnly");
            }
        }
        private byte[] CompressString(string input)
        {
            byte[] inputBytes = Encoding.UTF8.GetBytes(input);
            using (MemoryStream outputStream = new MemoryStream())
            {
                using (GZipStream gzipStream = new GZipStream(outputStream, CompressionMode.Compress))
                {
                    gzipStream.Write(inputBytes, 0, inputBytes.Length);
                }
                return outputStream.ToArray();
            }
        }
        public void WriteTS(byte[] content)
        {
            Write("HTTP/1.0 200 OK\r\n");
            Write("Access-Control-Allow-Origin: *\r\n");
            Write("Content-Length: " + content.Length + "\r\n");
            Write("Content-Type: application/octet-stream\r\n");
            if (CookieAppend.Count > 0)
            {
                Write("Set-Cookie: " + string.Join("; ", CookieAppend) + "; Path=/; HttpOnly\r\n");
            }
            CookieAppend.Clear();
            Write("Connection: close\r\n");
            Write("\r\n");
            server.SendMessage(e, content);
        }
        public void WriteM3u8(string filestr)
        {
            byte[] content = CompressString(filestr);
            Write("HTTP/1.0 200 OK\r\n");
            Write("Access-Control-Allow-Origin: *\r\n");
            Write("Content-Encoding: gzip\r\n");
            Write("Content-Length: " + content.Length + "\r\n");
            Write("Content-Type: application/vnd.apple.mpegurl\r\n");
            if (CookieAppend.Count > 0)
            {
                Write("Set-Cookie: " + string.Join("; ", CookieAppend) + "; Path=/; HttpOnly\r\n");
            }
            CookieAppend.Clear();
            Write("Connection: close\r\n");
            Write("\r\n");
            server.SendMessage(e,content);
        }
        public void WriteHtml(string htmlcontent) 
        {
            //Content - Encoding:
            //gzip
            //Content - Length:
            //729
            //Content - Type:
            //text / html; charset = UTF - 8
            //Date:
            //            Fri, 15 Sep 2023 09:08:43 GMT
            //
            //            Server:
            //nginx
            //Vary:
            //Accept - Encoding
            //X - Cache:
            //BYPASS
            //X - Powered - By:
            //PHP / 5.6.40
            Write("HTTP/1.0 200 OK\r\n");
            Write("Content-Length: "+ System.Text.Encoding.UTF8.GetBytes(htmlcontent).Length + "\r\n");
            Write("Content-Type: text/html; charset=UTF-8\r\n");
            if (CookieAppend.Count > 0)
            {
                Write("Set-Cookie: " + string.Join("; ", CookieAppend) + "; Path=/; HttpOnly\r\n");
            }
            CookieAppend.Clear();
            Write("Connection: close\r\n");
            Write("\r\n");
            Write(htmlcontent);
        }
        public void WriteSuccess() 
        {
            Write("HTTP/1.0 200 OK\r\n");
            Write("Content-Type: application/json; charset=UTF-8\r\n");
            if (CookieAppend.Count>0)
            {
                Write("Set-Cookie: "+ string.Join("; ",CookieAppend)+ "; Path=/; HttpOnly\r\n");
            }
            CookieAppend.Clear();
            Write("Connection: close\r\n");
            Write("\r\n");
        }
        public void WriteFailure()
        {
            Write("HTTP/1.0 404 File not found\r\n");
            Write("Connection: close\r\n");
            Write("\r\n");
        }
        public void Write(string txt) 
        {
            server.SendMessage(e, System.Text.Encoding.UTF8.GetBytes(txt));
        }
        public void Write(byte[] data)
        {
            server.SendMessage(e, data);
        }
        public void WsUpgrade(string secWebSocketKey) 
        {
            var secWebSocketAccept = sha1(secWebSocketKey + magic);
            Write("HTTP/1.1 101 Switching Protocols\r\n");
            Write("Connection: Upgrade\r\n");
            Write("Upgrade: websocket\r\n");
            Write("Sec-WebSocket-Accept: "+ secWebSocketAccept + "\r\n");
            Write("\r\n");
        }
        private string sha1(string str) 
        {
            var sha1 = new SHA1CryptoServiceProvider();
            byte[] str01 = Encoding.UTF8.GetBytes(str);
            byte[] str02 = sha1.ComputeHash(str01);
            return Convert.ToBase64String(str02);
        }

        
    }
}
